package com.garmin.gh.apps.wellnessmonitor.controller;

import java.io.IOException;
import java.util.List;

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.garmin.gh.apps.wellnessmonitor.dao.LoadSummaryDataDao;
import com.garmin.gh.apps.wellnessmonitor.dao.h2.WellnessDao;
import com.garmin.gh.apps.wellnessmonitor.domain.SummaryData;
import com.garmin.gh.apps.wellnessmonitor.domain.push.PushBody;
import com.garmin.gh.apps.wellnessmonitor.util.Consts;

@RestController
@EnableAutoConfiguration
@Component
@RequestMapping("/push")
public class WellnessPushController
{

    private static final Logger logger = LoggerFactory.getLogger(WellnessPushController.class);
    private static final String PUSH = "push";
    private static final String WARNING_MESSAGE = "Summarydata is not available";

    @Autowired
    WellnessDao wellnessDao;

    @Autowired
    LoadSummaryDataDao loadSummaryData;

    @Value("${oauth.consumerkey}")
    private String consumerkey;

    ObjectMapper jackson = new ObjectMapper();

   

    // Implementing push model

    @RequestMapping(value = "/activitySummaries", method = RequestMethod.POST)
    public ResponseEntity<String> acceptActivityPushedSummaries(@RequestBody @Valid PushBody activitySummaries)
        throws IOException
    {
        String activitySummaryInfo = jackson.writerWithDefaultPrettyPrinter().writeValueAsString(activitySummaries);
        logger.info("Activity pushed summary data:" + activitySummaryInfo);
        long timeStamp = System.currentTimeMillis();
        loadSummaryData.savePushData(Consts.ACTIVITIES, PUSH, consumerkey, timeStamp, activitySummaryInfo);
        logger.info("sending acknowledgement 200 to activitySummaries push notification service");
        return new ResponseEntity<String>(HttpStatus.OK);

    }

    @RequestMapping(value = "/activityUpdateSummaries", method = RequestMethod.POST)
    public ResponseEntity<String> acceptActivityUpdatePushedSummaries(
        @RequestBody @Valid PushBody manualActivitySummaries) throws IOException
    {
        String activityUpdateSummaryInfo = jackson.writerWithDefaultPrettyPrinter().writeValueAsString(
            manualActivitySummaries);
        logger.info("ActivityUpdate pushed summary data:" + activityUpdateSummaryInfo);
        long timeStamp = System.currentTimeMillis();
        loadSummaryData.savePushData(Consts.ACTIVITYUPDATES, PUSH, consumerkey, timeStamp,
            activityUpdateSummaryInfo);
        logger.info("sending acknowledgement 200 to activityUpdateSummaries push notification service");
        return new ResponseEntity<String>(HttpStatus.OK);

    }

    @RequestMapping(value = "/monitoringSummaries", method = RequestMethod.POST)
    public ResponseEntity<String> acceptMonitoringPushedSummaries(
        @RequestBody @Valid PushBody monitoringSummaries) throws IOException
    {
        String epochSummaryInfo = jackson.writerWithDefaultPrettyPrinter().writeValueAsString(monitoringSummaries);
        logger.info("Monitoring pushed summary data:" + epochSummaryInfo);
        long timeStamp = System.currentTimeMillis();
        loadSummaryData.savePushData(Consts.EPOCHS, PUSH, consumerkey, timeStamp, epochSummaryInfo);
        return new ResponseEntity<String>(HttpStatus.OK);

    }

    @RequestMapping(value = "/dailySummaries", method = RequestMethod.POST)
    public ResponseEntity<String> acceptDailiesPushedSummaries(@RequestBody @Valid PushBody dailySummaries)
        throws IOException
    {
        String dailiesSummaryInfo = jackson.writerWithDefaultPrettyPrinter().writeValueAsString(dailySummaries);
        logger.info(" dailies pushed summary data:" + dailiesSummaryInfo);
        long timeStamp = System.currentTimeMillis();
        loadSummaryData.savePushData(Consts.DAILIES, PUSH, consumerkey, timeStamp, dailiesSummaryInfo);
        logger.info("sending acknowledgement 200 to dailySummaries push notification service");
        return new ResponseEntity<String>(HttpStatus.OK);
    }

    @RequestMapping(value = "/sleepSummaries", method = RequestMethod.POST)
    public ResponseEntity<String> acceptSleepPushedSummaries(@RequestBody @Valid PushBody sleepSummaries)
        throws IOException
    {
        String sleepSummaryInfo = jackson.writerWithDefaultPrettyPrinter().writeValueAsString(sleepSummaries);
        logger.info("sleep pushed summary data:" + sleepSummaryInfo);
        long timeStamp = System.currentTimeMillis();
        loadSummaryData.savePushData(Consts.SLEEPS, PUSH, consumerkey, timeStamp, sleepSummaryInfo);
        logger.info("sending acknowledgement 200 to sleepSummaries push notification service");
        return new ResponseEntity<String>(HttpStatus.OK);

    }

    @RequestMapping(value = "/bodyCompSummaries", method = RequestMethod.POST)
    public ResponseEntity<String> acceptBodyCompositionPushedSummaries(
        @RequestBody @Valid PushBody bodyCompSummaries) throws IOException
    {
        String bodyCompsInfo = jackson.writerWithDefaultPrettyPrinter().writeValueAsString(bodyCompSummaries);
        logger.info("BodyComp pushed summary data:" + bodyCompsInfo);
        long timeStamp = System.currentTimeMillis();
        loadSummaryData.savePushData(Consts.BODYCOMPS, PUSH, consumerkey, timeStamp, bodyCompsInfo);
        logger.info("sending acknowledgement 200 to bodyCompSummaries push notification service");
        return new ResponseEntity<String>(HttpStatus.OK);

    }

    @RequestMapping(value = "/deregistrationSummaries", method = RequestMethod.POST)
    public ResponseEntity<String> acceptDeregPushedSummaries(@RequestBody @Valid PushBody deregSummaries)
        throws IOException
    {
        logger.info("Deregistration pushed summary data:"
            + jackson.writerWithDefaultPrettyPrinter().writeValueAsString(deregSummaries));
        return new ResponseEntity<String>(HttpStatus.OK);

    }

    
    // endpoints to monitor push data

    @RequestMapping(value = "/activitySummary/{consumerKey}", method = RequestMethod.GET, produces = "application/json")
    private String displayActivityPushedSummaryData(@PathVariable String consumerKey) throws JsonParseException,
        JsonMappingException, JsonProcessingException, IOException
    {
        List<SummaryData> pushedActivitySummaryList = wellnessDao.findPushSummaryDataByDomain(Consts.ACTIVITIES, PUSH,
            consumerKey);
        String activityInfo;
        if (pushedActivitySummaryList.size() > 0)
        {
            activityInfo = pushedActivitySummaryList.get(0).getDataLob();
        }
        else
        {
            activityInfo = jackson.writeValueAsString(Consts.ACTIVITIES + WARNING_MESSAGE);
        }
        return activityInfo;

    }

    @RequestMapping(value = "/activityUpdateSummary/{consumerKey}", method = RequestMethod.GET, produces = "application/json")
    private String displayActivityUpdatesPushedSummaryData(@PathVariable String consumerKey) throws JsonParseException,
        JsonMappingException, JsonProcessingException, IOException
    {
        List<SummaryData> pushedActivityUpdateSummaryDataList = wellnessDao.findPushSummaryDataByDomain(
            Consts.ACTIVITYUPDATES, PUSH, consumerKey);
        String activityUpdateInfo;
        
        if (pushedActivityUpdateSummaryDataList.size() > 0)
        {
            activityUpdateInfo = pushedActivityUpdateSummaryDataList.get(0).getDataLob();
        }
        else
        {
            activityUpdateInfo = jackson.writeValueAsString(Consts.ACTIVITYUPDATES + WARNING_MESSAGE);
        }
        return activityUpdateInfo;
    }

    @RequestMapping(value = "/dailiesSummary/{consumerKey}", method = RequestMethod.GET, produces = "application/json")
    private String displayDailiesPushedSummaryData(@PathVariable String consumerKey) throws JsonParseException,
        JsonMappingException, JsonProcessingException, IOException
    {
        List<SummaryData> pushedDailiesSummaryList = wellnessDao.findPushSummaryDataByDomain(Consts.DAILIES, PUSH,
            consumerKey);
        String dailiesInfo;
        if (pushedDailiesSummaryList.size() > 0)
        {
            dailiesInfo = pushedDailiesSummaryList.get(0).getDataLob();
        }
        else
        {
            dailiesInfo = jackson.writeValueAsString(Consts.DAILIES + WARNING_MESSAGE);
        }
        return dailiesInfo;

    }

    @RequestMapping(value = "/bodyCompsSummary/{consumerKey}", method = RequestMethod.GET, produces ="application/json")
    private String displayBodyCompsPushedSummaryData(@PathVariable String consumerKey) throws JsonParseException,
        JsonMappingException, JsonProcessingException, IOException
    {
        List<SummaryData> pushedBodyCompSummaryList = wellnessDao.findPushSummaryDataByDomain(Consts.BODYCOMPS, PUSH,
            consumerKey);
        String bodyCompInfo;
        if (pushedBodyCompSummaryList.size() > 0)
        {
            bodyCompInfo= pushedBodyCompSummaryList.get(0).getDataLob();
        }
        else
        {
            bodyCompInfo = jackson.writeValueAsString(Consts.BODYCOMPS + WARNING_MESSAGE);
        }
        return bodyCompInfo;

    }

    @RequestMapping(value = "/epochSummary/{consumerKey}", method = RequestMethod.GET, produces = "application/json")
    private String displayEpochsPushedSummaryData(@PathVariable String consumerKey) throws JsonParseException,
        JsonMappingException, JsonProcessingException, IOException
    {
        List<SummaryData> pushedEpochsSummaryList = wellnessDao.findPushSummaryDataByDomain(Consts.EPOCHS, PUSH,
            consumerKey);
        String epochInfo;
        if (pushedEpochsSummaryList.size() > 0)
        {
            epochInfo = pushedEpochsSummaryList.get(0).getDataLob();
        }
        else
        {
            epochInfo= jackson.writeValueAsString(Consts.EPOCHS + WARNING_MESSAGE);
        }
        return epochInfo;
    }

    @RequestMapping(value = "/sleepSummary/{consumerKey}", method = RequestMethod.GET, produces = "application/json")
    private String displaySleepsPushedSummaryData(@PathVariable String consumerKey) throws JsonParseException,
        JsonMappingException, JsonProcessingException, IOException
    {
        List<SummaryData> pushedSleepsSummaryList = wellnessDao.findPushSummaryDataByDomain(Consts.SLEEPS, PUSH,
            consumerKey);
        String sleepInfo;
        if (pushedSleepsSummaryList.size() > 0)
        {
            sleepInfo= pushedSleepsSummaryList.get(0).getDataLob();
        }
        else
        {
            sleepInfo= jackson.writeValueAsString(Consts.SLEEPS + WARNING_MESSAGE);
        }
        return sleepInfo;
    }

}
